package com.mingqijia.gassafety.webserver.utils;

import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.annotation.OperateLogFiled;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.webserver.service.BusinessNoticeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class LogUtil {


    @Autowired
    public void setHolder(ConfigureHolder holder) {
        this.holder = holder;
    }



    private static ConfigureHolder holder;

    /**
     * 1. 原实体和新实体，反射获得字段
     * 2. 遍历获得存在注解的字段
     * 3. 对比是否存在修改
     * 4. 获得注解内容，拼接
     */

    public static String compareEntity(Serializable newEntity, Serializable oldEntity, Class<?> entityClazz) {

        // 新实体的，存在注解的字段
        List<Field> fields = getAnnoFileds(entityClazz.getDeclaredFields(), OperateLogFiled.class);
        // 准备拼接
        StringBuilder sb = new StringBuilder();
        for (Field field : fields) {
            // 修改访问权限
            field.setAccessible(true);
            OperateLogFiled annotation = field.getAnnotation(OperateLogFiled.class);
            // 获得新旧值，进行对比
            Object newValue = null;
            Object oldValue = null;
            try {
                newValue = field.get(newEntity);
                oldValue = field.get(oldEntity);

                if (Objects.equals(newValue, oldValue) || (org.springframework.util.StringUtils.isEmpty(newValue)
                        && org.springframework.util.StringUtils.isEmpty(oldValue))) {
                    continue;
                }

                //类型判断，对需要做特定转换的类型进行处理
                String simpleName = field.getType().getSimpleName();
                if ("Date".equals(simpleName)) {
                    //从注解中获得时间格式
                    SimpleDateFormat sdf = new SimpleDateFormat(annotation.pattern());
                    newValue = sdf.format(newValue);
                    oldValue = sdf.format(oldValue);
                }
                if (StringUtils.isNotEmpty(annotation.dict())) {
                    oldValue = getDictName(oldValue, annotation.dict());
                    newValue = getDictName(newValue, annotation.dict());
                }
                if (StringUtils.isNotEmpty(annotation.codeName())) {
                    oldValue = getName(oldValue, annotation.codeName());
                    newValue = getName(newValue, annotation.codeName());
                }

            } catch (Exception e) {
                log.info("异常:{}", e.getMessage());
            }
            if (annotation.name().equals("周期")) {
                sb.append(annotation.name()).append("：由【").append(oldValue).append("】小时变更为【").append(newValue).append("】小时\n");
            } else if (annotation.name().equals("弹窗分钟")){
                sb.append(annotation.name()).append("：由【").append(oldValue).append("】分钟变更为【").append(newValue).append("】分钟\n");
            }else if (annotation.name().equals("弹窗秒")){
                sb.append(annotation.name()).append("：由【").append(oldValue).append("】秒变更为【").append(newValue).append("】秒\n");
            }else {
                sb.append(annotation.name()).append("：由【").append(oldValue).append("】变更为【").append(newValue).append("】\n");
            }
        }
        if (StringUtils.isNotEmpty(sb)) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

    private static String getName(Object value, String name) {
        String[] split = name.split(";");
        for (String s : split) {
            if (s.contains(value.toString())) {
                return s.substring(s.indexOf("-") + 1);
            }
        }
        return null;
    }

    public static String addOrDeleteEntity(Serializable newEntity, Class<?> entityClazz) {
        // 新实体的，存在注解的字段
        List<Field> fields = getAnnoFileds(entityClazz.getDeclaredFields(), OperateLogFiled.class);
        // 准备拼接
        StringBuilder sb = new StringBuilder();
        for (Field field : fields) {
            // 修改访问权限
            field.setAccessible(true);
            OperateLogFiled annotation = field.getAnnotation(OperateLogFiled.class);
            Object newValue = null;
            try {
                newValue = field.get(newEntity);
                if (Objects.isNull(newValue) || org.springframework.util.StringUtils.isEmpty(newValue)) {
                    continue;
                }
                //类型判断，对需要做特定转换的类型进行处理
                String simpleName = field.getType().getSimpleName();
                if ("Date".equals(simpleName)) {
                    //从注解中获得时间格式
                    SimpleDateFormat sdf = new SimpleDateFormat(annotation.pattern());
                    newValue = sdf.format(newValue);
                }
                if (StringUtils.isNotEmpty(annotation.dict())) {
                    newValue = getDictName(newValue, annotation.dict());
                }
            } catch (Exception e) {
                log.info("异常:{}", e.getMessage());
            }
            sb.append(annotation.name()).append("：").append(newValue).append("\n");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static String getDictName(Object value, String dictCode) {
        String spId = ApplicationUtils.getWorkingSpId();
        List<DictionaryItemRespDTO> list = holder.getDictionaryByKey(dictCode, spId);
        if (!CollectionUtils.isEmpty(list)) {
            List<DictionaryItemRespDTO> respDTOS = list.stream()
                    .filter(dict -> dict.getValue().equals(value.toString())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(respDTOS)) {
                return respDTOS.get(0).getName();
            }
        }
        return null;
    }

    public static List<Field> getAnnoFileds(Field[] fields, Class<OperateLogFiled> clazz) {
        List<Field> result = new ArrayList<>();
        // 判空
        if (fields.length == 0 || clazz == null) {
            return result;
        }
        // 从所有字段中，筛选出存在日志特定注解的字段
        Arrays.stream(fields).forEach(item -> {
            if (item.getAnnotation(clazz) != null) {
                result.add(item);
            }
        });
        return result;
    }

}
